/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.vod.gauss.File;

import fr.vod.gauss.encoder.Encoder;
import fr.vod.gauss.utils.Convert;

import java.io.InputStream;

/**
 *
 * @author drazanakoto
 */
public class FileImpl implements File {

    private int blockSize;
    private int packetSize;
    private InputStream fis;
    private Encoder encoder;
    private byte[] dataRead;

    /**
     *
     * @param fis
     * @param encoder
     */
    public FileImpl(InputStream fis, Encoder encoder) {
        this(fis, encoder, DEFAULT_BLOCK_SIZE, DEFAULT_PACKET_SIZE);
    }

    /**
     *
     * @param fis
     * @param encoder
     * @param blockSize
     * @param packetSize
     */
    public FileImpl(InputStream fis, Encoder encoder, int blockSize, int packetSize) {
        this.blockSize = blockSize;
        this.packetSize = packetSize;
        this.fis = fis;
        this.encoder = encoder;
        this.dataRead = new byte[blockSize];
    }

    /**
     *
     *
     * @return
     */
    @Override
    public byte[] create() {
        int[] result = new int[2 * packetSize + 1];
        int[] dataChoose;
        int[] symboles = encoder.generateSymboles(packetSize);
        int[] indiceData = encoder.generateDataIndice(blockSize, packetSize);

        /**
         *
         */
        System.arraycopy(indiceData, 0, result, 0, packetSize);
        
        
        System.arraycopy(symboles, 0, result, packetSize, packetSize);

        /**
         * get data corresponds to generate indice
         */
        dataChoose = getData(dataRead, indiceData);

        /**
         * calcul check Sum *
         */
        result[result.length - 1] = encoder.calculCheckSum(dataChoose, symboles);

        /**
         * convert int array result to byte array *
         */
        return intArrayToByteArray(result);
    }

    /**
     *
     * @return 
     * @throws Exception
     */
    @Override
    public int readNextBlock() throws Exception {
        return fis.read(dataRead);
    }

    /**
     *
     * @return
     */
    @Override
    public int getBlockSize() {
        return blockSize;
    }

    /**
     *
     * @param blockSize
     */
    @Override
    public void setBlockSize(int blockSize) {
        this.blockSize = blockSize;
    }

    /**
     *
     * @return
     */
    @Override
    public int getPacketSize() {
        return packetSize;
    }

    /**
     *
     * @param packetSize
     */
    @Override
    public void setPacketSize(int packetSize) {
        this.packetSize = packetSize;
    }

    /**
     *
     * @param data
     * @param indices
     * @return
     */
    protected int[] getData(byte[] data, int[] indices) {
        int[] result = new int[indices.length];
        byte tmp;
        for (int i = 0; i < indices.length; i++) {
            /**
             * get data correspond to indice *
             */
            tmp = data[indices[i]];
            /**
             * convert data to int *
             */
            result[i] = Convert.byteToUint8(tmp);
        }
        return result;
    }

    /**
     *
     * @param data
     * @return
     */
    protected byte[] intArrayToByteArray(int[] data) {
        byte[] result = new byte[data.length];
        for (int i = 0; i < data.length; i++) {
            result[i] = Convert.uint8ToByte(data[i]);
        }
        return result;
    }
}
